home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
c
/
criterrc.zip
/
CRITERR.ASM
< prev
next >
Wrap
Assembly Source File
|
1991-02-17
|
9KB
|
301 lines
TITLE CRITERR.ASM
SUBTTL TRAP CRITICAL ERRORS FROM W/IN C
IFDEF ??version ;TASM
%NOCONDS
ELSE ;MASM
.SFCOND ;DONT SHOW FALSE CONDITIONALS
ENDIF
; MODULE CRITERR.ASM
; JANUARY 1991
; PETER HYMAN (609) 799-2638
; 148 TENNYSON DRIVE
; PLAINSBORO, NJ 08536
; MODIFIED 2/16/91 SEE NOTES AT END OF SOURCE FOR DESCRIPTION OF CHANGES
;;;;; TWO FUNCTIONS ;;;;;
; FUNCTION NAME: CRITERR( ONOFF )
; INPUTS 1 = TRAP CRITICAL ERRORS, 0 TURN OFF TRAP
; RETURNS 0 IF SUCCESSFUL, 1 IF ALREADY INSTALLED
; FUNCTION NAME: CLRCRITERR( )
; CLEAR CRITICAL ERROR VARIABLES
; ON CRITICAL ERRORS, INT 24H HANDLER WILL RETURN AN IGNORE CODE TO DOS
; IF VERSION < 3, OR A FAIL CODE FOR DOS >= 3
; IF VERSION >= 3, DOS FUNCTION 59H IS CALLED ALSO, AND EXTENDED ERROR
; INFO IS ALSO PUT INTO STRUCTURE
;;;;; USES SIMPLIFIED SEGMENT DIRECTIVES. ASSEMBLE WITH I8086S, M, C OR L
;;;;; DEFINED
;;;;; ASSEMBLE AS MASM/TASM /mx /dI8086[S|M|C|L] criterr;
;;;;; TURBO ASSEMBLER YIELDS SMALLER CODE WITH /Q OPTION
IFDEF I8086S
.MODEL SMALL
p equ 4 ; p is offset into stack for args
SCODE EQU 1
ENDIF
IFDEF I8086M
.MODEL MEDIUM
p equ 6
LCODE equ 1
ENDIF
IFDEF I8086C
.MODEL COMPACT
p equ 4
SCODE EQU 1
LDATA EQU 1
ENDIF
IFDEF I8086L
.MODEL LARGE
p equ 6
LCODE EQU 1
LDATA EQU 1
ENDIF
IFNDEF I8086S
IFNDEF I8086M
IFNDEF I8086C
IFNDEF I8086L
%OUT NO MEMORY MODEL SPECIFIED
END
ENDIF
ENDIF
ENDIF
ENDIF
;;;;; FORMAT FOR CRITICAL ERROR HEADER BLOCK ;;;;;
;;;;; CERTAIN CHAR VARIABLES EXPANDED TO INT FOR PROPER ALLIGNMENT ;;;;;
CERR STRUC ; critical error structure
ceflag db ? ; flag to indicate critical error 1 = yes
cerrno db ? ; critical error number ; 2/16/91 changed to byte
cerrtype dw ? ; critical error type/action/drive, AX
drive db ? ; drive letter as a char
read_wr db ? ; read or write error 1 = write
disk_area db ? ; area of error, 0 = dos area, 1 = fat, 2 = dir, 3 = data
resp_mask db ? ; allowable responses (moot)
exterr db ? ; extended error number DOS >= 3 2/16/91 changed to byte
eclass db ? ; error class
action db ? ; action recommendations
locus db ? ; locus
nextdev dd ? ; next device pointer
attr dw ? ; device attribute
nxtfunc dw ? ; pointer to next strategy function
intfunc dw ? ; pointer to interrupt function
devname db 8 dup(?) ; device name
dummy db ? ; terminating null
CERR ENDS
; SEE DOS TECHNICAL REFERENCE FOR EXPLANATION OF CODES
;;;;; BEGIN DATA SEGMENT ;;;;; USING SIMPLIFIED SEGMENT DIRECTIVES
.DATA ; begin data segment
extrn __osmajor:byte ; operating system version
_criterrtrap db 0 ; critical error flag 1=trapped, 0 = off
;;;;; GLOBAL ;;;;;
public _cerr ; GLOBALS
_cerr CERR <> ; CRITICAL ERROR STRUCTURE BLOCK
.DATA? ; uninitialized data
_oldint24vec label dword
_oldint24off dw ? ; static vector to int 24 before trap
_oldint24seg dw ? ;
; PROCEDURE CRITERR( ONOFF )
; SETS ALTERNATE CRITICAL ERROR HANDLER
; USAGE: criterr( 1 ) to set, criterr( 0 ) to turn off
.CODE ; begin code segment
savds dw 0 ; save proper data segment
public _criterr
ifdef SCODE
_criterr proc
else
_criterr proc far
endif
push bp
mov bp, sp
push si
push di
mov ax, p[bp] ; see if a 0 or 1 was passed
test ax, ax ; non zero?
jne settrap ; 1, so set trap
removetrap:
cmp _criterrtrap, 1 ; see if installed
jne done ; not installed, so return
push ds
lds dx, _oldint24vec ; restore original int 24 vector
mov ax, 2524h
int 21h ; dos set vector function
pop ds
mov _criterrtrap, 0 ; reset flag
xor ax, ax ; set return code
jmp done
settrap:
cmp _criterrtrap, 1 ; see if installed
je done ; yes, so return (AX = 1)
mov cs:savds, ds ; move current data segment to savds
push es
mov ax,03524h ; save old vector to int 24
int 021h
mov _oldint24off,bx
mov _oldint24seg,es
pop es
push ds
mov dx, offset cs:int_service ; load address of new routine
mov ax,cs
mov ds,ax
mov ax,02524h ; set it
int 021h
pop ds
mov _criterrtrap, 1 ; set flag
xor ax, ax ;set return code
done:
push ax ; save AX
ifdef LCODE
call far ptr _clrcriterr ; reset values
else
call _clrcriterr
endif
pop ax
pop di
pop si
pop bp
ret ; return to caller, return code in AX
;;;;; NEW CRITICAL ERROR HANDLER ;;;;;
;;;;; SEE DOS TECHNICAL REFERENCE ;;;;;
int_service: ;int 24 trap goes here
push bp
mov bp,sp ; set to critical stack frame
push bx ; all used registers except AX must be
push cx ; saved !!!!!
push dx
push si
push di
push ds
push es
pushf
mov ds,cs:savds ; reset ds to program's ds
mov bx, di ; save DI
mov di, offset _cerr ; set di to point to structure cerr
mov ceflag[di], 1 ; set ceflag 2/16/91
mov cerrno[di], bl ; move to cerrno -- move byte only 2/16/91
mov cerrtype[di],ax ; save error type/drive number
test ax, 8000h ; char or block device
mov bx, ax
jnz response ; char device, so skip
add bl, 'A' ; add letter A
mov drive[di], bl ; move drive over
and bh, 00000110b ; leave only bits 1 and 2
shr bh,1 ; shift it over 1
mov disk_area[di], bh ; save area of error
mov bh, ah
response: ; determine response possibilities
and bh, 1 ; 2/16/91 this block moved from prev para.
mov read_wr[di], bh ; move read write flag
mov bh, ah
and bh, 00111000b ; leave only bits 3-5
shr bh,1
shr bh,1
shr bh,1 ; shift it over
mov resp_mask[di],bh ; save response mask
move_dev_header: ; move device header block
push ds ; set up data registers
pop es
mov bx,[bp] ; load bp to get segment for device header
mov ds,bx ; si contains offset of device header
mov di,offset _cerr.nextdev ; copy device header block
cld
mov cx,9
rep movsw ; move 18 bytes of device header block
push es
pop ds ; restore data registers
; now check for DOS version
xor ax,ax ; return code ignore for dos < 3
cmp __osmajor,3 ; dos >= 3?
jl doneint ; no
; prepare to get extended error
mov bx, 0
mov ah, 59h ; get dos extended error
int 21h ; call dos
mov di, offset _cerr; set di to point to cerr structure
mov exterr[di], al ; error code -- move byte only 2/16/91
mov eclass[di], bh ; error class
mov action[di], bl ; action
mov locus[di], ch ; locus
mov al, 3 ; return fail code
doneint:
popf
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop bp ; restore stack frame
iret ; return from interrupt
_criterr endp
;;;;; FUNCTION TO CLEAR CRITICAL ERROR STATUS ;;;;;
;;;;; USAGE: clrcriterr()
public _clrcriterr
ifdef SCODE
_clrcriterr proc ; function to clear critical error number
else
_clrcriterr proc far ; function to clear critical error number
endif
push bp
mov bp,sp
push di
push ds
pop es
xor ax,ax ; zero entire structure
mov di, offset _cerr
mov cx, size _cerr ; get size of entire block
rep stosb
pop di
pop bp
ret
_clrcriterr endp
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; PROGRAM MODIFICATIONS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; MODIFIED 2/16/91 TO INCLUDE THE FOLLOWING
; STRUCTURE MEMBER ceflag ADDED
; THIS WAS REQUIRED TO DETECT CRITICAL ERRORS, SINCE cerrno COULD HAVE
; A VALUE OF 0 WHICH WOULD INDICATE A WRITE PROTECT ERROR. ceflag WILL
; BE SET IT THERE WAS A CRITICAL ERROR
; CALLS TO EXTERNAL FUNCTION _dos_exterr REMOVED
; STUCTURE MEMBERS cerrno AND exterr CHANGED TO BYTE SIZE
; STRUCTURE MEMBER pad REMOVED BECAUSE ABOVE MADE IT UNNECESSARY
; THE CODE WHICH SET THE read_wr STRUCTURE MEMBER WAS MOVED TO JUST
; BELOW THE response: LABEL SINCE IT WAS NOT CORRECTLY LOCATED PREVIOUSLY
; AND WOULD NEVER BE SET FOR NON-DISK ERRORS
; TEST